package graphics.engine;

import java.io.*;
import java.nio.*;

import javax.media.opengl.GL;

import com.sun.opengl.util.BufferUtil;

public class ProgramShader 
{
	public int ProgramShaderID;
	
	private int fragmentShaderID;
	private int vertexShaderID;
	
	public int WorldMatrixUniformID;
	public int ProjectionMatrixUniformID;
	public int ViewMatrixUniformID;
	public int TextureUniformID;
	public int isTextured;
	
	public boolean beingInitialized = false;
	public boolean isInitialized = false;
	
	public ProgramShader()
	{

	}

	public void init(GL gl)
	{
		if(!this.beingInitialized && !this.isInitialized)
		{
			this.beingInitialized = true;
			
			try 
			{
				this.vertexShaderID = loadShader(gl, GL.GL_VERTEX_SHADER, "./bin/graphics/engine/VertexShader.glsl");
			} 
			catch (IOException e) 
			{
				e.printStackTrace();
			}
			try 
			{
				this.fragmentShaderID = loadShader(gl, GL.GL_FRAGMENT_SHADER,  "./bin/graphics/engine/FragmentShader.glsl");
			} 
			catch (IOException e) 
			{
				e.printStackTrace();
			}
			
			this.ProgramShaderID = gl.glCreateProgram();
			gl.glAttachShader(this.ProgramShaderID, this.vertexShaderID);
			gl.glAttachShader(this.ProgramShaderID, this.fragmentShaderID);	
			gl.glLinkProgram(this.ProgramShaderID);
			
			this.WorldMatrixUniformID = gl.glGetUniformLocation(this.ProgramShaderID, "World");
			this.ViewMatrixUniformID = gl.glGetUniformLocation(this.ProgramShaderID, "View");		
			this.ProjectionMatrixUniformID = gl.glGetUniformLocation(this.ProgramShaderID, "Projection");
			this.TextureUniformID = gl.glGetUniformLocation(this.ProgramShaderID, "texture");
			this.isTextured = gl.glGetUniformLocation(this.ProgramShaderID, "isTextured");
			
			this.beingInitialized = false;
			this.isInitialized = true;
		}
	}
	
	public int loadShader(GL gl, int shaderType, String path) throws IOException
	{
		int shaderID = gl.glCreateShader(shaderType);
		BufferedReader reader = new BufferedReader(new FileReader(path));
		String currentLine;
		String[] source = new String[1];
		source[0] = "";

		while ( (currentLine = reader.readLine()) != null)
		{
			source[0] += currentLine + "\n";
		}
		gl.glShaderSource(shaderID, 1, source, null);	
		gl.glCompileShader(shaderID);

		IntBuffer intBuffer = BufferUtil.newIntBuffer(1);
		gl.glGetShaderiv(shaderID, GL.GL_INFO_LOG_LENGTH, intBuffer);

		int length = intBuffer.get();
		if(length > 1)
		{
			intBuffer.flip();
			ByteBuffer infoLog = BufferUtil.newByteBuffer(length);
			gl.glGetShaderInfoLog(shaderID, length, intBuffer, infoLog);	

			byte[] infoBytes = new byte[length];
			infoLog.get(infoBytes);
		}	
		reader.close();
		return shaderID;
	}
}
